import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

from sklearn.datasets import make_gaussian_quantiles
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier

## 设置属性防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False

def run():
   ## 创建数据
   X1,Y1=make_gaussian_quantiles(cov=2.,n_samples=200,n_features=2,n_classes=2,random_state=0)#创建符合高斯分布的数据集
   X2,Y2=make_gaussian_quantiles(mean=(3,3),cov=1.5,n_samples=300,n_features=2,n_classes=2,random_state=0)
   X=np.concatenate((X1,X2))
   Y=np.concatenate((Y1,1-Y2))

   # 构建adaboost模型
   abc=AdaBoostClassifier(DecisionTreeClassifier(max_depth=2),
                          algorithm='SAMME.R',# 可以不写
                          n_estimators=200)
   # 数据量大的时候，可以增加内部分类器的树深度，也可以不限制树深
   # max_depth树深，数据量大的时候，一般范围在10——100之间
   # 数据量小的时候，一般可以设置树深度较小，或者n_estimators较小
   # n_estimators 迭代次数或者最大弱分类器数：200次
   # base_estimator：DecisionTreeClassifier 选择弱分类器，默认为CART树
   # algorithm：SAMME 和SAMME.R 。运算规则，后者是优化算法，以概率调整权重，迭代速度快，
   # 需要能计算概率的分类器支持
   # learning_rate：0<v<=1，默认为1，正则项 衰减指数
   # loss：linear、‘square’exponential’。误差计算公式：一般用linear足够
   abc.fit(X,Y)
   plot_step=0.02
   X_min,X_max=X[:,0].min()-1,X[:,0].max()+1
   Y_min,Y_max=X[:,1].min()-1,X[:,1].max()+1
   XX,YY=np.meshgrid(np.arange(X_min,X_max,plot_step),np.arange(Y_min,Y_max,plot_step))
   # 预测
   Z=abc.predict(np.c_[XX.ravel(),YY.ravel()])

   # 设置维度
   Z=Z.reshape(XX.shape)

   ## 画图
   plot_colors="br"
   class_names="AB"

   plt.figure(figsize=(10,5),facecolor='w')
   # 局部子图
   plt.subplot(121)
   plt.pcolormesh(XX,YY,Z,cmap=plt.cm.Paired)
   for i,n,c in zip(range(2),class_names,plot_colors):
       idx=np.where(Y==i)
       plt.scatter(X[idx,0],X[idx,1],c=c,cmap=plt.cm.Paired,label=u'类别%s' % n)
   plt.xlim(X_min,X_max)
   plt.ylim(Y_min,Y_max)
   plt.xlabel('x')
   plt.ylabel('y')
   plt.legend(loc='upper right')
   plt.title(u'AdaBoost分类结果,正确率为:%.2f%%' % (abc.score(X,Y)*100))

   # 获取决策函数的数值
   twoclass_output=abc.decision_function(X)
   # 获取范围
   plot_range=(twoclass_output.min(),twoclass_output.max())
   plt.subplot(122)
   for i,n,c in zip(range(2),class_names,plot_colors):
       # 直方图
       plt.hist(twoclass_output[Y==i],
                bins=20,
                range=plot_range,
                facecolor=c,
                label=u'类别 %s' % n,
                alpha=.5)
   X1,X2,Y1,Y2=plt.axis()
   plt.axis((X1,X2,Y1,Y2*1.2))
   plt.legend(loc='upper right')
   plt.xlabel(u'决策函数值')
   plt.ylabel(u'样本数')
   plt.title(u'AdaBoost的决策值')

   plt.tight_layout()
   plt.subplots_adjust(wspace=0.35)
   plt.show()

run()